package repositories

import (
	"gitee.com/kessil/chicory/internal/models"
	"gitee.com/kessil/chicory/internal/utils"
	"github.com/syndtr/goleveldb/leveldb/errors"
	"xorm.io/xorm"
)

type RoleRepository struct {
	*Repository[models.Role]
	db *xorm.Engine
}

func NewRoleRepository(db *xorm.Engine) *RoleRepository {
	return &RoleRepository{
		Repository: NewRepository[models.Role](db),
		db:         db,
	}
}

func (r *RoleRepository) GetRoleWithUsers(id int64) (*models.Role, error) {
	role, err := r.GetByID(id)
	if err != nil {
		return nil, err
	}

	// 获取角色用户
	var users []models.User
	err = r.db.Table("user").
		Join("INNER", "user_role", "user.id = user_role.userId").
		Where("user_role.roleId = ?", id).
		Find(&users)
	if err != nil {
		return nil, err
	}

	role.Users = users
	return role, nil
}

func (r *RoleRepository) GetRoleByName(name string) (*models.Role, error) {
	var role models.Role
	has, err := r.db.Where("name = ?", name).Get(&role)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, nil
	}
	return &role, nil
}

func (r *RoleRepository) GetRoleWithPermissions(id int64) (*models.RoleListPageItem, error) {
	var role *models.RoleListPageItem
	has, err := r.db.ID(id).Get(&role)
	if err != nil {
		return nil, err
	}

	if !has {
		return nil, errors.ErrNotFound
	}

	// 获取角色权限
	var permissions []int64
	err = r.db.Select("permissionId").Table("role_permission").
		Where("role_permission.roleId = ?", id).
		Find(&permissions)
	if err != nil {
		return nil, err
	}

	role.PermissionIds = permissions
	return role, nil
}

func (r *RoleRepository) ListRolesWithPermissions(filters map[string]interface{}, pageNo, pageSize int) (*models.RoleListPageRes, error) {
	utils.Printf(filters)
	var entities []models.RoleListPageItem
	session := r.db.NewSession()

	// 应用筛选条件
	if len(filters) > 0 {
		for field, value := range filters {
			if err := r.addFilterCondition(session, field, value); err != nil {
				return nil, err
			}
		}
	}

	total, err := session.Count(new(models.Role))
	if err != nil {
		utils.Error(err.Error())
		return nil, err
	}

	// 重新应用筛选条件，因为session被Count重置了
	if len(filters) > 0 {
		for field, value := range filters {
			if err := r.addFilterCondition(session, field, value); err != nil {
				return nil, err
			}
		}
	}
	// session = session
	if pageNo > 0 && pageSize > 0 {
		session = session.Limit(pageSize, (pageNo-1)*pageSize)
	}

	err = session.Table("role").Find(&entities)
	if err != nil {
		utils.Error(err.Error())
		return nil, err
	}

	pr := NewPermissionRepository(r.db)
	for k, v := range entities {
		// 获取角色权限ids
		perms, err := pr.GetPermissionsByRoleId(v.Id)

		if err != nil {
			utils.Error(err.Error())
			return nil, err
		}

		entities[k].PermissionIds = make([]int64, 0)

		for _, i := range perms {
			entities[k].PermissionIds = append(entities[k].PermissionIds, i.Id)
		}

	}

	return &models.RoleListPageRes{PageData: entities, Total: total}, nil
}

func (r *RoleRepository) AddRolePermission(roleId, permissionId int64) error {
	rolePermission := &models.RolePermission{
		RoleId:       roleId,
		PermissionId: permissionId,
	}
	if has, err := r.db.Table("role_permission").Where("roleId = ? AND permissionId = ?", roleId, permissionId).Exist(); has {
		return err
	}
	_, err := r.db.Insert(rolePermission)
	return err
}

func (r *RoleRepository) RemoveRolePermission(roleId, permissionId int64) error {
	_, err := r.db.Where("roleId = ? AND roleId = ?", roleId, permissionId).Delete(&models.RolePermission{})
	return err
}

func (r *RoleRepository) BatchAddUsersRole(roleId int64, userIds []int64) error {
	for _, uid := range userIds {
		userRole := models.UserRole{
			UserId: uid,
			RoleId: roleId,
		}
		_, err := r.db.Insert(&userRole)
		if err != nil {
			return err
		}
	}
	return nil
}

func (r *RoleRepository) BatchRemoveUsersRole(roleId int64, userIds []int64) error {
	for _, uid := range userIds {
		userRole := models.UserRole{
			UserId: uid,
			RoleId: roleId,
		}
		_, err := r.db.Delete(&userRole)
		if err != nil {
			return err
		}
	}
	return nil
}
